/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Generated by j/c/g/ipc/invalidation/common/proto_wrapper_generator
package com.google.ipc.invalidation.ticl.proto;

import com.google.ipc.invalidation.util.Bytes;
import com.google.ipc.invalidation.util.ProtoWrapper;
import com.google.ipc.invalidation.util.ProtoWrapper.ValidationException;
import com.google.ipc.invalidation.util.TextBuilder;
import com.google.protobuf.nano.MessageNano;
import com.google.protobuf.nano.InvalidProtocolBufferNanoException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


public interface ClientProtocol {

  public static final class Version extends ProtoWrapper {
    public static Version create(int majorVersion,
        int minorVersion) {
      return new Version(majorVersion, minorVersion);
    }

    private final int majorVersion;
    private final int minorVersion;

    private Version(Integer majorVersion,
        Integer minorVersion) throws ValidationArgumentException {
      required("major_version", majorVersion);
      nonNegative("major_version", majorVersion);
      this.majorVersion = majorVersion;
      required("minor_version", minorVersion);
      nonNegative("minor_version", minorVersion);
      this.minorVersion = minorVersion;
    }

    public int getMajorVersion() { return majorVersion; }

    public int getMinorVersion() { return minorVersion; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof Version)) { return false; }
      Version other = (Version) obj;
      return majorVersion == other.majorVersion
          && minorVersion == other.minorVersion;
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + hash(majorVersion);
      result = result * 31 + hash(minorVersion);
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<Version:");
      builder.append(" major_version=").append(majorVersion);
      builder.append(" minor_version=").append(minorVersion);
      builder.append('>');
    }

    public static Version parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.Version(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static Version fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.Version message) {
      if (message == null) { return null; }
      return new Version(message.majorVersion,
          message.minorVersion);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.Version toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.Version msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.Version();
      msg.majorVersion = majorVersion;
      msg.minorVersion = minorVersion;
      return msg;
    }
  }

  public static final class ProtocolVersion extends ProtoWrapper {
    public static ProtocolVersion create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version) {
      return new ProtocolVersion(version);
    }

    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version;

    private ProtocolVersion(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version) throws ValidationArgumentException {
      required("version", version);
      this.version = version;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version getVersion() { return version; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ProtocolVersion)) { return false; }
      ProtocolVersion other = (ProtocolVersion) obj;
      return equals(version, other.version);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + version.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ProtocolVersion:");
      builder.append(" version=").append(version);
      builder.append('>');
    }

    public static ProtocolVersion parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolVersion(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ProtocolVersion fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolVersion message) {
      if (message == null) { return null; }
      return new ProtocolVersion(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version.fromMessageNano(message.version));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolVersion toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolVersion msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolVersion();
      msg.version = version.toMessageNano();
      return msg;
    }
  }

  public static final class ClientVersion extends ProtoWrapper {
    public static ClientVersion create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version,
        String platform,
        String language,
        String applicationInfo) {
      return new ClientVersion(version, platform, language, applicationInfo);
    }

    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version;
    private final String platform;
    private final String language;
    private final String applicationInfo;

    private ClientVersion(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version,
        String platform,
        String language,
        String applicationInfo) throws ValidationArgumentException {
      required("version", version);
      this.version = version;
      required("platform", platform);
      this.platform = platform;
      required("language", language);
      this.language = language;
      required("application_info", applicationInfo);
      this.applicationInfo = applicationInfo;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version getVersion() { return version; }

    public String getPlatform() { return platform; }

    public String getLanguage() { return language; }

    public String getApplicationInfo() { return applicationInfo; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ClientVersion)) { return false; }
      ClientVersion other = (ClientVersion) obj;
      return equals(version, other.version)
          && equals(platform, other.platform)
          && equals(language, other.language)
          && equals(applicationInfo, other.applicationInfo);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + version.hashCode();
      result = result * 31 + platform.hashCode();
      result = result * 31 + language.hashCode();
      result = result * 31 + applicationInfo.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ClientVersion:");
      builder.append(" version=").append(version);
      builder.append(" platform=").append(platform);
      builder.append(" language=").append(language);
      builder.append(" application_info=").append(applicationInfo);
      builder.append('>');
    }

    public static ClientVersion parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientVersion(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ClientVersion fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientVersion message) {
      if (message == null) { return null; }
      return new ClientVersion(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version.fromMessageNano(message.version),
          message.platform,
          message.language,
          message.applicationInfo);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientVersion toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientVersion msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientVersion();
      msg.version = version.toMessageNano();
      msg.platform = platform;
      msg.language = language;
      msg.applicationInfo = applicationInfo;
      return msg;
    }
  }

  public static final class StatusP extends ProtoWrapper {
    public interface Code {
      public static final int SUCCESS = 1;
      public static final int TRANSIENT_FAILURE = 2;
      public static final int PERMANENT_FAILURE = 3;
    }

    public static StatusP create(int code,
        String description) {
      return new StatusP(code, description);
    }

    private final long __hazzerBits;
    private final int code;
    private final String description;

    private StatusP(Integer code,
        String description) throws ValidationArgumentException {
      int hazzerBits = 0;
      required("code", code);
      this.code = code;
      if (description != null) {
        hazzerBits |= 0x1;
        this.description = description;
      } else {
        this.description = "";
      }
      this.__hazzerBits = hazzerBits;
    }

    public int getCode() { return code; }

    public String getDescription() { return description; }
    public boolean hasDescription() { return (0x1 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof StatusP)) { return false; }
      StatusP other = (StatusP) obj;
      return __hazzerBits == other.__hazzerBits
          && code == other.code
          && (!hasDescription() || equals(description, other.description));
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      result = result * 31 + hash(code);
      if (hasDescription()) {
        result = result * 31 + description.hashCode();
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<StatusP:");
      builder.append(" code=").append(code);
      if (hasDescription()) {
        builder.append(" description=").append(description);
      }
      builder.append('>');
    }

    public static StatusP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.StatusP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static StatusP fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.StatusP message) {
      if (message == null) { return null; }
      return new StatusP(message.code,
          message.description);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.StatusP toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.StatusP msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.StatusP();
      msg.code = code;
      msg.description = hasDescription() ? description : null;
      return msg;
    }
  }

  public static final class ObjectIdP extends ProtoWrapper {
    public static ObjectIdP create(int source,
        Bytes name) {
      return new ObjectIdP(source, name);
    }

    private final int source;
    private final Bytes name;

    private ObjectIdP(Integer source,
        Bytes name) throws ValidationArgumentException {
      required("source", source);
      nonNegative("source", source);
      this.source = source;
      required("name", name);
      this.name = name;
    }

    public int getSource() { return source; }

    public Bytes getName() { return name; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ObjectIdP)) { return false; }
      ObjectIdP other = (ObjectIdP) obj;
      return source == other.source
          && equals(name, other.name);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + hash(source);
      result = result * 31 + name.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ObjectIdP:");
      builder.append(" source=").append(source);
      builder.append(" name=").append(name);
      builder.append('>');
    }

    public static ObjectIdP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ObjectIdP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ObjectIdP fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ObjectIdP message) {
      if (message == null) { return null; }
      return new ObjectIdP(message.source,
          Bytes.fromByteArray(message.name));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ObjectIdP toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ObjectIdP msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ObjectIdP();
      msg.source = source;
      msg.name = name.getByteArray();
      return msg;
    }
  }

  public static final class ApplicationClientIdP extends ProtoWrapper {
    public static ApplicationClientIdP create(Integer clientType,
        Bytes clientName) {
      return new ApplicationClientIdP(clientType, clientName);
    }

    private final long __hazzerBits;
    private final int clientType;
    private final Bytes clientName;

    private ApplicationClientIdP(Integer clientType,
        Bytes clientName) throws ValidationArgumentException {
      int hazzerBits = 0;
      if (clientType != null) {
        hazzerBits |= 0x1;
        this.clientType = clientType;
      } else {
        this.clientType = 0;
      }
      required("client_name", clientName);
      nonEmpty("client_name", clientName);
      this.clientName = clientName;
      this.__hazzerBits = hazzerBits;
    }

    public int getClientType() { return clientType; }
    public boolean hasClientType() { return (0x1 & __hazzerBits) != 0; }

    public Bytes getClientName() { return clientName; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ApplicationClientIdP)) { return false; }
      ApplicationClientIdP other = (ApplicationClientIdP) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasClientType() || clientType == other.clientType)
          && equals(clientName, other.clientName);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasClientType()) {
        result = result * 31 + hash(clientType);
      }
      result = result * 31 + clientName.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ApplicationClientIdP:");
      if (hasClientType()) {
        builder.append(" client_type=").append(clientType);
      }
      builder.append(" client_name=").append(clientName);
      builder.append('>');
    }

    public static ApplicationClientIdP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ApplicationClientIdP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ApplicationClientIdP fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ApplicationClientIdP message) {
      if (message == null) { return null; }
      return new ApplicationClientIdP(message.clientType,
          Bytes.fromByteArray(message.clientName));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ApplicationClientIdP toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ApplicationClientIdP msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ApplicationClientIdP();
      msg.clientType = hasClientType() ? clientType : null;
      msg.clientName = clientName.getByteArray();
      return msg;
    }
  }

  public static final class InvalidationP extends ProtoWrapper {
    public static final class Builder {
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP objectId;
      public boolean isKnownVersion;
      public long version;
      public Bytes payload;
      public Boolean isTrickleRestart;
      public Builder(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP objectId,
          boolean isKnownVersion,
          long version) {
        this.objectId = objectId;this.isKnownVersion = isKnownVersion;this.version = version;}

      public InvalidationP build() {
        return new InvalidationP(objectId, isKnownVersion, version, payload, isTrickleRestart);
      }
    }

    public static InvalidationP create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP objectId,
        boolean isKnownVersion,
        long version,
        Bytes payload,
        Boolean isTrickleRestart) {
      return new InvalidationP(objectId, isKnownVersion, version, payload, isTrickleRestart);
    }

    private final long __hazzerBits;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP objectId;
    private final boolean isKnownVersion;
    private final long version;
    private final Bytes payload;
    private final boolean isTrickleRestart;

    private InvalidationP(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP objectId,
        Boolean isKnownVersion,
        Long version,
        Bytes payload,
        Boolean isTrickleRestart) throws ValidationArgumentException {
      int hazzerBits = 0;
      required("object_id", objectId);
      this.objectId = objectId;
      required("is_known_version", isKnownVersion);
      this.isKnownVersion = isKnownVersion;
      required("version", version);
      nonNegative("version", version);
      this.version = version;
      if (payload != null) {
        hazzerBits |= 0x1;
        this.payload = payload;
      } else {
        this.payload = Bytes.EMPTY_BYTES;
      }
      if (isTrickleRestart != null) {
        hazzerBits |= 0x2;
        this.isTrickleRestart = isTrickleRestart;
      } else {
        this.isTrickleRestart = true;
      }
      this.__hazzerBits = hazzerBits;
      check(isKnownVersion || (isTrickleRestart == null || isTrickleRestart),
          "is_trickle_restart required if not is_known_version");
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP getObjectId() { return objectId; }

    public boolean getIsKnownVersion() { return isKnownVersion; }

    public long getVersion() { return version; }

    public Bytes getPayload() { return payload; }
    public boolean hasPayload() { return (0x1 & __hazzerBits) != 0; }

    public boolean getIsTrickleRestart() { return isTrickleRestart; }
    public boolean hasIsTrickleRestart() { return (0x2 & __hazzerBits) != 0; }

    public Builder toBuilder() {
      Builder builder = new Builder(objectId, isKnownVersion, version);
      if (hasPayload()) {
        builder.payload = payload;
      }
      if (hasIsTrickleRestart()) {
        builder.isTrickleRestart = isTrickleRestart;
      }
      return builder;
    }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof InvalidationP)) { return false; }
      InvalidationP other = (InvalidationP) obj;
      return __hazzerBits == other.__hazzerBits
          && equals(objectId, other.objectId)
          && isKnownVersion == other.isKnownVersion
          && version == other.version
          && (!hasPayload() || equals(payload, other.payload))
          && (!hasIsTrickleRestart() || isTrickleRestart == other.isTrickleRestart);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      result = result * 31 + objectId.hashCode();
      result = result * 31 + hash(isKnownVersion);
      result = result * 31 + hash(version);
      if (hasPayload()) {
        result = result * 31 + payload.hashCode();
      }
      if (hasIsTrickleRestart()) {
        result = result * 31 + hash(isTrickleRestart);
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<InvalidationP:");
      builder.append(" object_id=").append(objectId);
      builder.append(" is_known_version=").append(isKnownVersion);
      builder.append(" version=").append(version);
      if (hasPayload()) {
        builder.append(" payload=").append(payload);
      }
      if (hasIsTrickleRestart()) {
        builder.append(" is_trickle_restart=").append(isTrickleRestart);
      }
      builder.append('>');
    }

    public static InvalidationP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static InvalidationP fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationP message) {
      if (message == null) { return null; }
      return new InvalidationP(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP.fromMessageNano(message.objectId),
          message.isKnownVersion,
          message.version,
          Bytes.fromByteArray(message.payload),
          message.isTrickleRestart);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationP toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationP msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationP();
      msg.objectId = objectId.toMessageNano();
      msg.isKnownVersion = isKnownVersion;
      msg.version = version;
      msg.payload = hasPayload() ? payload.getByteArray() : null;
      msg.isTrickleRestart = hasIsTrickleRestart() ? isTrickleRestart : null;
      return msg;
    }
  }

  public static final class RegistrationP extends ProtoWrapper {
    public interface OpType {
      public static final int REGISTER = 1;
      public static final int UNREGISTER = 2;
    }

    public static RegistrationP create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP objectId,
        int opType) {
      return new RegistrationP(objectId, opType);
    }

    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP objectId;
    private final int opType;

    private RegistrationP(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP objectId,
        Integer opType) throws ValidationArgumentException {
      required("object_id", objectId);
      this.objectId = objectId;
      required("op_type", opType);
      this.opType = opType;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP getObjectId() { return objectId; }

    public int getOpType() { return opType; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RegistrationP)) { return false; }
      RegistrationP other = (RegistrationP) obj;
      return equals(objectId, other.objectId)
          && opType == other.opType;
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + objectId.hashCode();
      result = result * 31 + hash(opType);
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RegistrationP:");
      builder.append(" object_id=").append(objectId);
      builder.append(" op_type=").append(opType);
      builder.append('>');
    }

    public static RegistrationP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RegistrationP fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationP message) {
      if (message == null) { return null; }
      return new RegistrationP(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP.fromMessageNano(message.objectId),
          message.opType);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationP toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationP msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationP();
      msg.objectId = objectId.toMessageNano();
      msg.opType = opType;
      return msg;
    }
  }

  public static final class RegistrationSummary extends ProtoWrapper {
    public static RegistrationSummary create(int numRegistrations,
        Bytes registrationDigest) {
      return new RegistrationSummary(numRegistrations, registrationDigest);
    }

    private final int numRegistrations;
    private final Bytes registrationDigest;

    private RegistrationSummary(Integer numRegistrations,
        Bytes registrationDigest) throws ValidationArgumentException {
      required("num_registrations", numRegistrations);
      nonNegative("num_registrations", numRegistrations);
      this.numRegistrations = numRegistrations;
      required("registration_digest", registrationDigest);
      nonEmpty("registration_digest", registrationDigest);
      this.registrationDigest = registrationDigest;
    }

    public int getNumRegistrations() { return numRegistrations; }

    public Bytes getRegistrationDigest() { return registrationDigest; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RegistrationSummary)) { return false; }
      RegistrationSummary other = (RegistrationSummary) obj;
      return numRegistrations == other.numRegistrations
          && equals(registrationDigest, other.registrationDigest);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + hash(numRegistrations);
      result = result * 31 + registrationDigest.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RegistrationSummary:");
      builder.append(" num_registrations=").append(numRegistrations);
      builder.append(" registration_digest=").append(registrationDigest);
      builder.append('>');
    }

    public static RegistrationSummary parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSummary(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RegistrationSummary fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSummary message) {
      if (message == null) { return null; }
      return new RegistrationSummary(message.numRegistrations,
          Bytes.fromByteArray(message.registrationDigest));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSummary toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSummary msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSummary();
      msg.numRegistrations = numRegistrations;
      msg.registrationDigest = registrationDigest.getByteArray();
      return msg;
    }
  }

  public static final class ClientHeader extends ProtoWrapper {
    public static ClientHeader create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion protocolVersion,
        Bytes clientToken,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary registrationSummary,
        long clientTimeMs,
        long maxKnownServerTimeMs,
        String messageId,
        Integer clientType) {
      return new ClientHeader(protocolVersion, clientToken, registrationSummary, clientTimeMs, maxKnownServerTimeMs, messageId, clientType);
    }

    private final long __hazzerBits;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion protocolVersion;
    private final Bytes clientToken;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary registrationSummary;
    private final long clientTimeMs;
    private final long maxKnownServerTimeMs;
    private final String messageId;
    private final int clientType;

    private ClientHeader(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion protocolVersion,
        Bytes clientToken,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary registrationSummary,
        Long clientTimeMs,
        Long maxKnownServerTimeMs,
        String messageId,
        Integer clientType) throws ValidationArgumentException {
      int hazzerBits = 0;
      required("protocol_version", protocolVersion);
      this.protocolVersion = protocolVersion;
      if (clientToken != null) {
        hazzerBits |= 0x1;
        nonEmpty("client_token", clientToken);
        this.clientToken = clientToken;
      } else {
        this.clientToken = Bytes.EMPTY_BYTES;
      }
      this.registrationSummary = registrationSummary;
      required("client_time_ms", clientTimeMs);
      nonNegative("client_time_ms", clientTimeMs);
      this.clientTimeMs = clientTimeMs;
      required("max_known_server_time_ms", maxKnownServerTimeMs);
      nonNegative("max_known_server_time_ms", maxKnownServerTimeMs);
      this.maxKnownServerTimeMs = maxKnownServerTimeMs;
      if (messageId != null) {
        hazzerBits |= 0x2;
        nonEmpty("message_id", messageId);
        this.messageId = messageId;
      } else {
        this.messageId = "";
      }
      if (clientType != null) {
        hazzerBits |= 0x4;
        this.clientType = clientType;
      } else {
        this.clientType = 0;
      }
      this.__hazzerBits = hazzerBits;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion getProtocolVersion() { return protocolVersion; }

    public Bytes getClientToken() { return clientToken; }
    public boolean hasClientToken() { return (0x1 & __hazzerBits) != 0; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary getNullableRegistrationSummary() { return registrationSummary; }

    public long getClientTimeMs() { return clientTimeMs; }

    public long getMaxKnownServerTimeMs() { return maxKnownServerTimeMs; }

    public String getMessageId() { return messageId; }
    public boolean hasMessageId() { return (0x2 & __hazzerBits) != 0; }

    public int getClientType() { return clientType; }
    public boolean hasClientType() { return (0x4 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ClientHeader)) { return false; }
      ClientHeader other = (ClientHeader) obj;
      return __hazzerBits == other.__hazzerBits
          && equals(protocolVersion, other.protocolVersion)
          && (!hasClientToken() || equals(clientToken, other.clientToken))
          && equals(registrationSummary, other.registrationSummary)
          && clientTimeMs == other.clientTimeMs
          && maxKnownServerTimeMs == other.maxKnownServerTimeMs
          && (!hasMessageId() || equals(messageId, other.messageId))
          && (!hasClientType() || clientType == other.clientType);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      result = result * 31 + protocolVersion.hashCode();
      if (hasClientToken()) {
        result = result * 31 + clientToken.hashCode();
      }
      if (registrationSummary != null) {
        result = result * 31 + registrationSummary.hashCode();
      }
      result = result * 31 + hash(clientTimeMs);
      result = result * 31 + hash(maxKnownServerTimeMs);
      if (hasMessageId()) {
        result = result * 31 + messageId.hashCode();
      }
      if (hasClientType()) {
        result = result * 31 + hash(clientType);
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ClientHeader:");
      builder.append(" protocol_version=").append(protocolVersion);
      if (hasClientToken()) {
        builder.append(" client_token=").append(clientToken);
      }
      if (registrationSummary != null) {
        builder.append(" registration_summary=").append(registrationSummary);
      }
      builder.append(" client_time_ms=").append(clientTimeMs);
      builder.append(" max_known_server_time_ms=").append(maxKnownServerTimeMs);
      if (hasMessageId()) {
        builder.append(" message_id=").append(messageId);
      }
      if (hasClientType()) {
        builder.append(" client_type=").append(clientType);
      }
      builder.append('>');
    }

    public static ClientHeader parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientHeader(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ClientHeader fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientHeader message) {
      if (message == null) { return null; }
      return new ClientHeader(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion.fromMessageNano(message.protocolVersion),
          Bytes.fromByteArray(message.clientToken),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary.fromMessageNano(message.registrationSummary),
          message.clientTimeMs,
          message.maxKnownServerTimeMs,
          message.messageId,
          message.clientType);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientHeader toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientHeader msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientHeader();
      msg.protocolVersion = protocolVersion.toMessageNano();
      msg.clientToken = hasClientToken() ? clientToken.getByteArray() : null;
      msg.registrationSummary = this.registrationSummary != null ? registrationSummary.toMessageNano() : null;
      msg.clientTimeMs = clientTimeMs;
      msg.maxKnownServerTimeMs = maxKnownServerTimeMs;
      msg.messageId = hasMessageId() ? messageId : null;
      msg.clientType = hasClientType() ? clientType : null;
      return msg;
    }
  }

  public static final class ClientToServerMessage extends ProtoWrapper {
    public static ClientToServerMessage create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientHeader header,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InitializeMessage initializeMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationMessage registrationMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncMessage registrationSyncMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage invalidationAckMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoMessage infoMessage) {
      return new ClientToServerMessage(header, initializeMessage, registrationMessage, registrationSyncMessage, invalidationAckMessage, infoMessage);
    }

    private final long __hazzerBits;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientHeader header;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.InitializeMessage initializeMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationMessage registrationMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncMessage registrationSyncMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage invalidationAckMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoMessage infoMessage;

    private ClientToServerMessage(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientHeader header,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InitializeMessage initializeMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationMessage registrationMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncMessage registrationSyncMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage invalidationAckMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoMessage infoMessage) throws ValidationArgumentException {
      int hazzerBits = 0;
      required("header", header);
      this.header = header;
      this.initializeMessage = initializeMessage;
      this.registrationMessage = registrationMessage;
      this.registrationSyncMessage = registrationSyncMessage;
      this.invalidationAckMessage = invalidationAckMessage;
      if (infoMessage != null) {
        hazzerBits |= 0x1;
        this.infoMessage = infoMessage;
      } else {
        this.infoMessage = com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoMessage.DEFAULT_INSTANCE;
      }
      this.__hazzerBits = hazzerBits;
      check((initializeMessage != null) ^ header.hasClientToken(), 
          "There should either be a client token or an initialization request");
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientHeader getHeader() { return header; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.InitializeMessage getNullableInitializeMessage() { return initializeMessage; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationMessage getNullableRegistrationMessage() { return registrationMessage; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncMessage getNullableRegistrationSyncMessage() { return registrationSyncMessage; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage getNullableInvalidationAckMessage() { return invalidationAckMessage; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoMessage getInfoMessage() { return infoMessage; }
    public boolean hasInfoMessage() { return (0x1 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ClientToServerMessage)) { return false; }
      ClientToServerMessage other = (ClientToServerMessage) obj;
      return __hazzerBits == other.__hazzerBits
          && equals(header, other.header)
          && equals(initializeMessage, other.initializeMessage)
          && equals(registrationMessage, other.registrationMessage)
          && equals(registrationSyncMessage, other.registrationSyncMessage)
          && equals(invalidationAckMessage, other.invalidationAckMessage)
          && (!hasInfoMessage() || equals(infoMessage, other.infoMessage));
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      result = result * 31 + header.hashCode();
      if (initializeMessage != null) {
        result = result * 31 + initializeMessage.hashCode();
      }
      if (registrationMessage != null) {
        result = result * 31 + registrationMessage.hashCode();
      }
      if (registrationSyncMessage != null) {
        result = result * 31 + registrationSyncMessage.hashCode();
      }
      if (invalidationAckMessage != null) {
        result = result * 31 + invalidationAckMessage.hashCode();
      }
      if (hasInfoMessage()) {
        result = result * 31 + infoMessage.hashCode();
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ClientToServerMessage:");
      builder.append(" header=").append(header);
      if (initializeMessage != null) {
        builder.append(" initialize_message=").append(initializeMessage);
      }
      if (registrationMessage != null) {
        builder.append(" registration_message=").append(registrationMessage);
      }
      if (registrationSyncMessage != null) {
        builder.append(" registration_sync_message=").append(registrationSyncMessage);
      }
      if (invalidationAckMessage != null) {
        builder.append(" invalidation_ack_message=").append(invalidationAckMessage);
      }
      if (hasInfoMessage()) {
        builder.append(" info_message=").append(infoMessage);
      }
      builder.append('>');
    }

    public static ClientToServerMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientToServerMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ClientToServerMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientToServerMessage message) {
      if (message == null) { return null; }
      return new ClientToServerMessage(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientHeader.fromMessageNano(message.header),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.InitializeMessage.fromMessageNano(message.initializeMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationMessage.fromMessageNano(message.registrationMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncMessage.fromMessageNano(message.registrationSyncMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage.fromMessageNano(message.invalidationAckMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoMessage.fromMessageNano(message.infoMessage));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientToServerMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientToServerMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientToServerMessage();
      msg.header = header.toMessageNano();
      msg.initializeMessage = this.initializeMessage != null ? initializeMessage.toMessageNano() : null;
      msg.registrationMessage = this.registrationMessage != null ? registrationMessage.toMessageNano() : null;
      msg.registrationSyncMessage = this.registrationSyncMessage != null ? registrationSyncMessage.toMessageNano() : null;
      msg.invalidationAckMessage = this.invalidationAckMessage != null ? invalidationAckMessage.toMessageNano() : null;
      msg.infoMessage = hasInfoMessage() ? infoMessage.toMessageNano() : null;
      return msg;
    }
  }

  public static final class InitializeMessage extends ProtoWrapper {
    public interface DigestSerializationType {
      public static final int BYTE_BASED = 1;
      public static final int NUMBER_BASED = 2;
    }

    public static InitializeMessage create(int clientType,
        Bytes nonce,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ApplicationClientIdP applicationClientId,
        int digestSerializationType) {
      return new InitializeMessage(clientType, nonce, applicationClientId, digestSerializationType);
    }

    private final int clientType;
    private final Bytes nonce;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ApplicationClientIdP applicationClientId;
    private final int digestSerializationType;

    private InitializeMessage(Integer clientType,
        Bytes nonce,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ApplicationClientIdP applicationClientId,
        Integer digestSerializationType) throws ValidationArgumentException {
      required("client_type", clientType);
      nonNegative("client_type", clientType);
      this.clientType = clientType;
      required("nonce", nonce);
      this.nonce = nonce;
      required("application_client_id", applicationClientId);
      this.applicationClientId = applicationClientId;
      required("digest_serialization_type", digestSerializationType);
      this.digestSerializationType = digestSerializationType;
    }

    public int getClientType() { return clientType; }

    public Bytes getNonce() { return nonce; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ApplicationClientIdP getApplicationClientId() { return applicationClientId; }

    public int getDigestSerializationType() { return digestSerializationType; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof InitializeMessage)) { return false; }
      InitializeMessage other = (InitializeMessage) obj;
      return clientType == other.clientType
          && equals(nonce, other.nonce)
          && equals(applicationClientId, other.applicationClientId)
          && digestSerializationType == other.digestSerializationType;
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + hash(clientType);
      result = result * 31 + nonce.hashCode();
      result = result * 31 + applicationClientId.hashCode();
      result = result * 31 + hash(digestSerializationType);
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<InitializeMessage:");
      builder.append(" client_type=").append(clientType);
      builder.append(" nonce=").append(nonce);
      builder.append(" application_client_id=").append(applicationClientId);
      builder.append(" digest_serialization_type=").append(digestSerializationType);
      builder.append('>');
    }

    public static InitializeMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InitializeMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static InitializeMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InitializeMessage message) {
      if (message == null) { return null; }
      return new InitializeMessage(message.clientType,
          Bytes.fromByteArray(message.nonce),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.ApplicationClientIdP.fromMessageNano(message.applicationClientId),
          message.digestSerializationType);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InitializeMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InitializeMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InitializeMessage();
      msg.clientType = clientType;
      msg.nonce = nonce.getByteArray();
      msg.applicationClientId = applicationClientId.toMessageNano();
      msg.digestSerializationType = digestSerializationType;
      return msg;
    }
  }

  public static final class RegistrationMessage extends ProtoWrapper {
    public static RegistrationMessage create(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP> registration) {
      return new RegistrationMessage(registration);
    }

    private final List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP> registration;

    private RegistrationMessage(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP> registration) throws ValidationArgumentException {
      this.registration = required("registration", registration);
    }

    public List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP> getRegistration() { return registration; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RegistrationMessage)) { return false; }
      RegistrationMessage other = (RegistrationMessage) obj;
      return equals(registration, other.registration);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + registration.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RegistrationMessage:");
      builder.append(" registration=[").append(registration).append(']');
      builder.append('>');
    }

    public static RegistrationMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RegistrationMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationMessage message) {
      if (message == null) { return null; }
      List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP> registration = new ArrayList<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP>(message.registration.length);
      for (int i = 0; i < message.registration.length; i++) {
        registration.add(com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP.fromMessageNano(message.registration[i]));
      }
      return new RegistrationMessage(registration);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationMessage();
      msg.registration = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationP[registration.size()];
      for (int i = 0; i < msg.registration.length; i++) {
        msg.registration[i] = registration.get(i).toMessageNano();
      }
      return msg;
    }
  }

  public static final class RegistrationSyncMessage extends ProtoWrapper {
    public static RegistrationSyncMessage create(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSubtree> subtree) {
      return new RegistrationSyncMessage(subtree);
    }

    private final List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSubtree> subtree;

    private RegistrationSyncMessage(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSubtree> subtree) throws ValidationArgumentException {
      this.subtree = required("subtree", subtree);
    }

    public List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSubtree> getSubtree() { return subtree; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RegistrationSyncMessage)) { return false; }
      RegistrationSyncMessage other = (RegistrationSyncMessage) obj;
      return equals(subtree, other.subtree);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + subtree.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RegistrationSyncMessage:");
      builder.append(" subtree=[").append(subtree).append(']');
      builder.append('>');
    }

    public static RegistrationSyncMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RegistrationSyncMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncMessage message) {
      if (message == null) { return null; }
      List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSubtree> subtree = new ArrayList<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSubtree>(message.subtree.length);
      for (int i = 0; i < message.subtree.length; i++) {
        subtree.add(com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSubtree.fromMessageNano(message.subtree[i]));
      }
      return new RegistrationSyncMessage(subtree);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncMessage();
      msg.subtree = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSubtree[subtree.size()];
      for (int i = 0; i < msg.subtree.length; i++) {
        msg.subtree[i] = subtree.get(i).toMessageNano();
      }
      return msg;
    }
  }

  public static final class RegistrationSubtree extends ProtoWrapper {
    public static RegistrationSubtree create(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP> registeredObject) {
      return new RegistrationSubtree(registeredObject);
    }

    public static final RegistrationSubtree DEFAULT_INSTANCE = new RegistrationSubtree(null);

    private final List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP> registeredObject;

    private RegistrationSubtree(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP> registeredObject) {
      this.registeredObject = optional("registered_object", registeredObject);
    }

    public List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP> getRegisteredObject() { return registeredObject; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RegistrationSubtree)) { return false; }
      RegistrationSubtree other = (RegistrationSubtree) obj;
      return equals(registeredObject, other.registeredObject);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + registeredObject.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RegistrationSubtree:");
      builder.append(" registered_object=[").append(registeredObject).append(']');
      builder.append('>');
    }

    public static RegistrationSubtree parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSubtree(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RegistrationSubtree fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSubtree message) {
      if (message == null) { return null; }
      List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP> registeredObject = new ArrayList<com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP>(message.registeredObject.length);
      for (int i = 0; i < message.registeredObject.length; i++) {
        registeredObject.add(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ObjectIdP.fromMessageNano(message.registeredObject[i]));
      }
      return new RegistrationSubtree(registeredObject);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSubtree toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSubtree msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSubtree();
      msg.registeredObject = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ObjectIdP[registeredObject.size()];
      for (int i = 0; i < msg.registeredObject.length; i++) {
        msg.registeredObject[i] = registeredObject.get(i).toMessageNano();
      }
      return msg;
    }
  }

  public static final class InfoMessage extends ProtoWrapper {
    public static InfoMessage create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientVersion clientVersion,
        Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> configParameter,
        Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> performanceCounter,
        Boolean serverRegistrationSummaryRequested,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientConfigP clientConfig) {
      return new InfoMessage(clientVersion, configParameter, performanceCounter, serverRegistrationSummaryRequested, clientConfig);
    }

    public static final InfoMessage DEFAULT_INSTANCE = new InfoMessage(null, null, null, null, null);

    private final long __hazzerBits;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientVersion clientVersion;
    private final List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> configParameter;
    private final List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> performanceCounter;
    private final boolean serverRegistrationSummaryRequested;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientConfigP clientConfig;

    private InfoMessage(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientVersion clientVersion,
        Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> configParameter,
        Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> performanceCounter,
        Boolean serverRegistrationSummaryRequested,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientConfigP clientConfig) {
      int hazzerBits = 0;
      this.clientVersion = clientVersion;
      this.configParameter = optional("config_parameter", configParameter);
      this.performanceCounter = optional("performance_counter", performanceCounter);
      if (serverRegistrationSummaryRequested != null) {
        hazzerBits |= 0x1;
        this.serverRegistrationSummaryRequested = serverRegistrationSummaryRequested;
      } else {
        this.serverRegistrationSummaryRequested = false;
      }
      this.clientConfig = clientConfig;
      this.__hazzerBits = hazzerBits;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientVersion getNullableClientVersion() { return clientVersion; }

    public List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> getConfigParameter() { return configParameter; }

    public List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> getPerformanceCounter() { return performanceCounter; }

    public boolean getServerRegistrationSummaryRequested() { return serverRegistrationSummaryRequested; }
    public boolean hasServerRegistrationSummaryRequested() { return (0x1 & __hazzerBits) != 0; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientConfigP getNullableClientConfig() { return clientConfig; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof InfoMessage)) { return false; }
      InfoMessage other = (InfoMessage) obj;
      return __hazzerBits == other.__hazzerBits
          && equals(clientVersion, other.clientVersion)
          && equals(configParameter, other.configParameter)
          && equals(performanceCounter, other.performanceCounter)
          && (!hasServerRegistrationSummaryRequested() || serverRegistrationSummaryRequested == other.serverRegistrationSummaryRequested)
          && equals(clientConfig, other.clientConfig);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (clientVersion != null) {
        result = result * 31 + clientVersion.hashCode();
      }
      result = result * 31 + configParameter.hashCode();
      result = result * 31 + performanceCounter.hashCode();
      if (hasServerRegistrationSummaryRequested()) {
        result = result * 31 + hash(serverRegistrationSummaryRequested);
      }
      if (clientConfig != null) {
        result = result * 31 + clientConfig.hashCode();
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<InfoMessage:");
      if (clientVersion != null) {
        builder.append(" client_version=").append(clientVersion);
      }
      builder.append(" config_parameter=[").append(configParameter).append(']');
      builder.append(" performance_counter=[").append(performanceCounter).append(']');
      if (hasServerRegistrationSummaryRequested()) {
        builder.append(" server_registration_summary_requested=").append(serverRegistrationSummaryRequested);
      }
      if (clientConfig != null) {
        builder.append(" client_config=").append(clientConfig);
      }
      builder.append('>');
    }

    public static InfoMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static InfoMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoMessage message) {
      if (message == null) { return null; }
      List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> configParameter = new ArrayList<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord>(message.configParameter.length);
      for (int i = 0; i < message.configParameter.length; i++) {
        configParameter.add(com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord.fromMessageNano(message.configParameter[i]));
      }
      List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord> performanceCounter = new ArrayList<com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord>(message.performanceCounter.length);
      for (int i = 0; i < message.performanceCounter.length; i++) {
        performanceCounter.add(com.google.ipc.invalidation.ticl.proto.ClientProtocol.PropertyRecord.fromMessageNano(message.performanceCounter[i]));
      }
      return new InfoMessage(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientVersion.fromMessageNano(message.clientVersion),
          configParameter,
          performanceCounter,
          message.serverRegistrationSummaryRequested,
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.ClientConfigP.fromMessageNano(message.clientConfig));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoMessage();
      msg.clientVersion = this.clientVersion != null ? clientVersion.toMessageNano() : null;
      msg.configParameter = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.PropertyRecord[configParameter.size()];
      for (int i = 0; i < msg.configParameter.length; i++) {
        msg.configParameter[i] = configParameter.get(i).toMessageNano();
      }
      msg.performanceCounter = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.PropertyRecord[performanceCounter.size()];
      for (int i = 0; i < msg.performanceCounter.length; i++) {
        msg.performanceCounter[i] = performanceCounter.get(i).toMessageNano();
      }
      msg.serverRegistrationSummaryRequested = hasServerRegistrationSummaryRequested() ? serverRegistrationSummaryRequested : null;
      msg.clientConfig = this.clientConfig != null ? clientConfig.toMessageNano() : null;
      return msg;
    }
  }

  public static final class PropertyRecord extends ProtoWrapper {
    public static PropertyRecord create(String name,
        Integer value) {
      return new PropertyRecord(name, value);
    }

    public static final PropertyRecord DEFAULT_INSTANCE = new PropertyRecord(null, null);

    private final long __hazzerBits;
    private final String name;
    private final int value;

    private PropertyRecord(String name,
        Integer value) {
      int hazzerBits = 0;
      if (name != null) {
        hazzerBits |= 0x1;
        this.name = name;
      } else {
        this.name = "";
      }
      if (value != null) {
        hazzerBits |= 0x2;
        this.value = value;
      } else {
        this.value = 0;
      }
      this.__hazzerBits = hazzerBits;
    }

    public String getName() { return name; }
    public boolean hasName() { return (0x1 & __hazzerBits) != 0; }

    public int getValue() { return value; }
    public boolean hasValue() { return (0x2 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof PropertyRecord)) { return false; }
      PropertyRecord other = (PropertyRecord) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasName() || equals(name, other.name))
          && (!hasValue() || value == other.value);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasName()) {
        result = result * 31 + name.hashCode();
      }
      if (hasValue()) {
        result = result * 31 + hash(value);
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<PropertyRecord:");
      if (hasName()) {
        builder.append(" name=").append(name);
      }
      if (hasValue()) {
        builder.append(" value=").append(value);
      }
      builder.append('>');
    }

    public static PropertyRecord parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.PropertyRecord(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static PropertyRecord fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.PropertyRecord message) {
      if (message == null) { return null; }
      return new PropertyRecord(message.name,
          message.value);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.PropertyRecord toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.PropertyRecord msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.PropertyRecord();
      msg.name = hasName() ? name : null;
      msg.value = hasValue() ? value : null;
      return msg;
    }
  }

  public static final class ServerHeader extends ProtoWrapper {
    public static final class Builder {
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion protocolVersion;
      public Bytes clientToken;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary registrationSummary;
      public long serverTimeMs;
      public String messageId;
      public Builder(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion protocolVersion,
          Bytes clientToken,
          long serverTimeMs) {
        this.protocolVersion = protocolVersion;this.clientToken = clientToken;this.serverTimeMs = serverTimeMs;}

      public ServerHeader build() {
        return new ServerHeader(protocolVersion, clientToken, registrationSummary, serverTimeMs, messageId);
      }
    }

    public static ServerHeader create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion protocolVersion,
        Bytes clientToken,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary registrationSummary,
        long serverTimeMs,
        String messageId) {
      return new ServerHeader(protocolVersion, clientToken, registrationSummary, serverTimeMs, messageId);
    }

    private final long __hazzerBits;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion protocolVersion;
    private final Bytes clientToken;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary registrationSummary;
    private final long serverTimeMs;
    private final String messageId;

    private ServerHeader(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion protocolVersion,
        Bytes clientToken,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary registrationSummary,
        Long serverTimeMs,
        String messageId) throws ValidationArgumentException {
      int hazzerBits = 0;
      required("protocol_version", protocolVersion);
      this.protocolVersion = protocolVersion;
      required("client_token", clientToken);
      nonEmpty("client_token", clientToken);
      this.clientToken = clientToken;
      this.registrationSummary = registrationSummary;
      required("server_time_ms", serverTimeMs);
      nonNegative("server_time_ms", serverTimeMs);
      this.serverTimeMs = serverTimeMs;
      if (messageId != null) {
        hazzerBits |= 0x1;
        nonEmpty("message_id", messageId);
        this.messageId = messageId;
      } else {
        this.messageId = "";
      }
      this.__hazzerBits = hazzerBits;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion getProtocolVersion() { return protocolVersion; }

    public Bytes getClientToken() { return clientToken; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary getNullableRegistrationSummary() { return registrationSummary; }

    public long getServerTimeMs() { return serverTimeMs; }

    public String getMessageId() { return messageId; }
    public boolean hasMessageId() { return (0x1 & __hazzerBits) != 0; }

    public Builder toBuilder() {
      Builder builder = new Builder(protocolVersion, clientToken, serverTimeMs);
      if (this.registrationSummary != null) {
        builder.registrationSummary = registrationSummary;
      }
      if (hasMessageId()) {
        builder.messageId = messageId;
      }
      return builder;
    }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ServerHeader)) { return false; }
      ServerHeader other = (ServerHeader) obj;
      return __hazzerBits == other.__hazzerBits
          && equals(protocolVersion, other.protocolVersion)
          && equals(clientToken, other.clientToken)
          && equals(registrationSummary, other.registrationSummary)
          && serverTimeMs == other.serverTimeMs
          && (!hasMessageId() || equals(messageId, other.messageId));
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      result = result * 31 + protocolVersion.hashCode();
      result = result * 31 + clientToken.hashCode();
      if (registrationSummary != null) {
        result = result * 31 + registrationSummary.hashCode();
      }
      result = result * 31 + hash(serverTimeMs);
      if (hasMessageId()) {
        result = result * 31 + messageId.hashCode();
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ServerHeader:");
      builder.append(" protocol_version=").append(protocolVersion);
      builder.append(" client_token=").append(clientToken);
      if (registrationSummary != null) {
        builder.append(" registration_summary=").append(registrationSummary);
      }
      builder.append(" server_time_ms=").append(serverTimeMs);
      if (hasMessageId()) {
        builder.append(" message_id=").append(messageId);
      }
      builder.append('>');
    }

    public static ServerHeader parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerHeader(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ServerHeader fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerHeader message) {
      if (message == null) { return null; }
      return new ServerHeader(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolVersion.fromMessageNano(message.protocolVersion),
          Bytes.fromByteArray(message.clientToken),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSummary.fromMessageNano(message.registrationSummary),
          message.serverTimeMs,
          message.messageId);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerHeader toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerHeader msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerHeader();
      msg.protocolVersion = protocolVersion.toMessageNano();
      msg.clientToken = clientToken.getByteArray();
      msg.registrationSummary = this.registrationSummary != null ? registrationSummary.toMessageNano() : null;
      msg.serverTimeMs = serverTimeMs;
      msg.messageId = hasMessageId() ? messageId : null;
      return msg;
    }
  }

  public static final class ServerToClientMessage extends ProtoWrapper {
    public static final class Builder {
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ServerHeader header;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.TokenControlMessage tokenControlMessage;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage invalidationMessage;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatusMessage registrationStatusMessage;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncRequestMessage registrationSyncRequestMessage;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ConfigChangeMessage configChangeMessage;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoRequestMessage infoRequestMessage;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ErrorMessage errorMessage;
      public Builder(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ServerHeader header) {
        this.header = header;}

      public ServerToClientMessage build() {
        return new ServerToClientMessage(header, tokenControlMessage, invalidationMessage, registrationStatusMessage, registrationSyncRequestMessage, configChangeMessage, infoRequestMessage, errorMessage);
      }
    }

    public static ServerToClientMessage create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ServerHeader header,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.TokenControlMessage tokenControlMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage invalidationMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatusMessage registrationStatusMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncRequestMessage registrationSyncRequestMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ConfigChangeMessage configChangeMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoRequestMessage infoRequestMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ErrorMessage errorMessage) {
      return new ServerToClientMessage(header, tokenControlMessage, invalidationMessage, registrationStatusMessage, registrationSyncRequestMessage, configChangeMessage, infoRequestMessage, errorMessage);
    }

    private final long __hazzerBits;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ServerHeader header;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.TokenControlMessage tokenControlMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage invalidationMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatusMessage registrationStatusMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncRequestMessage registrationSyncRequestMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ConfigChangeMessage configChangeMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoRequestMessage infoRequestMessage;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ErrorMessage errorMessage;

    private ServerToClientMessage(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ServerHeader header,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.TokenControlMessage tokenControlMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage invalidationMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatusMessage registrationStatusMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncRequestMessage registrationSyncRequestMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ConfigChangeMessage configChangeMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoRequestMessage infoRequestMessage,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ErrorMessage errorMessage) throws ValidationArgumentException {
      int hazzerBits = 0;
      required("header", header);
      this.header = header;
      if (tokenControlMessage != null) {
        hazzerBits |= 0x1;
        this.tokenControlMessage = tokenControlMessage;
      } else {
        this.tokenControlMessage = com.google.ipc.invalidation.ticl.proto.ClientProtocol.TokenControlMessage.DEFAULT_INSTANCE;
      }
      this.invalidationMessage = invalidationMessage;
      this.registrationStatusMessage = registrationStatusMessage;
      if (registrationSyncRequestMessage != null) {
        hazzerBits |= 0x2;
        this.registrationSyncRequestMessage = registrationSyncRequestMessage;
      } else {
        this.registrationSyncRequestMessage = com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncRequestMessage.DEFAULT_INSTANCE;
      }
      if (configChangeMessage != null) {
        hazzerBits |= 0x4;
        this.configChangeMessage = configChangeMessage;
      } else {
        this.configChangeMessage = com.google.ipc.invalidation.ticl.proto.ClientProtocol.ConfigChangeMessage.DEFAULT_INSTANCE;
      }
      this.infoRequestMessage = infoRequestMessage;
      this.errorMessage = errorMessage;
      this.__hazzerBits = hazzerBits;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ServerHeader getHeader() { return header; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.TokenControlMessage getTokenControlMessage() { return tokenControlMessage; }
    public boolean hasTokenControlMessage() { return (0x1 & __hazzerBits) != 0; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage getNullableInvalidationMessage() { return invalidationMessage; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatusMessage getNullableRegistrationStatusMessage() { return registrationStatusMessage; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncRequestMessage getRegistrationSyncRequestMessage() { return registrationSyncRequestMessage; }
    public boolean hasRegistrationSyncRequestMessage() { return (0x2 & __hazzerBits) != 0; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ConfigChangeMessage getConfigChangeMessage() { return configChangeMessage; }
    public boolean hasConfigChangeMessage() { return (0x4 & __hazzerBits) != 0; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoRequestMessage getNullableInfoRequestMessage() { return infoRequestMessage; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ErrorMessage getNullableErrorMessage() { return errorMessage; }

    public Builder toBuilder() {
      Builder builder = new Builder(header);
      if (hasTokenControlMessage()) {
        builder.tokenControlMessage = tokenControlMessage;
      }
      if (this.invalidationMessage != null) {
        builder.invalidationMessage = invalidationMessage;
      }
      if (this.registrationStatusMessage != null) {
        builder.registrationStatusMessage = registrationStatusMessage;
      }
      if (hasRegistrationSyncRequestMessage()) {
        builder.registrationSyncRequestMessage = registrationSyncRequestMessage;
      }
      if (hasConfigChangeMessage()) {
        builder.configChangeMessage = configChangeMessage;
      }
      if (this.infoRequestMessage != null) {
        builder.infoRequestMessage = infoRequestMessage;
      }
      if (this.errorMessage != null) {
        builder.errorMessage = errorMessage;
      }
      return builder;
    }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ServerToClientMessage)) { return false; }
      ServerToClientMessage other = (ServerToClientMessage) obj;
      return __hazzerBits == other.__hazzerBits
          && equals(header, other.header)
          && (!hasTokenControlMessage() || equals(tokenControlMessage, other.tokenControlMessage))
          && equals(invalidationMessage, other.invalidationMessage)
          && equals(registrationStatusMessage, other.registrationStatusMessage)
          && (!hasRegistrationSyncRequestMessage() || equals(registrationSyncRequestMessage, other.registrationSyncRequestMessage))
          && (!hasConfigChangeMessage() || equals(configChangeMessage, other.configChangeMessage))
          && equals(infoRequestMessage, other.infoRequestMessage)
          && equals(errorMessage, other.errorMessage);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      result = result * 31 + header.hashCode();
      if (hasTokenControlMessage()) {
        result = result * 31 + tokenControlMessage.hashCode();
      }
      if (invalidationMessage != null) {
        result = result * 31 + invalidationMessage.hashCode();
      }
      if (registrationStatusMessage != null) {
        result = result * 31 + registrationStatusMessage.hashCode();
      }
      if (hasRegistrationSyncRequestMessage()) {
        result = result * 31 + registrationSyncRequestMessage.hashCode();
      }
      if (hasConfigChangeMessage()) {
        result = result * 31 + configChangeMessage.hashCode();
      }
      if (infoRequestMessage != null) {
        result = result * 31 + infoRequestMessage.hashCode();
      }
      if (errorMessage != null) {
        result = result * 31 + errorMessage.hashCode();
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ServerToClientMessage:");
      builder.append(" header=").append(header);
      if (hasTokenControlMessage()) {
        builder.append(" token_control_message=").append(tokenControlMessage);
      }
      if (invalidationMessage != null) {
        builder.append(" invalidation_message=").append(invalidationMessage);
      }
      if (registrationStatusMessage != null) {
        builder.append(" registration_status_message=").append(registrationStatusMessage);
      }
      if (hasRegistrationSyncRequestMessage()) {
        builder.append(" registration_sync_request_message=").append(registrationSyncRequestMessage);
      }
      if (hasConfigChangeMessage()) {
        builder.append(" config_change_message=").append(configChangeMessage);
      }
      if (infoRequestMessage != null) {
        builder.append(" info_request_message=").append(infoRequestMessage);
      }
      if (errorMessage != null) {
        builder.append(" error_message=").append(errorMessage);
      }
      builder.append('>');
    }

    public static ServerToClientMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerToClientMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ServerToClientMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerToClientMessage message) {
      if (message == null) { return null; }
      return new ServerToClientMessage(com.google.ipc.invalidation.ticl.proto.ClientProtocol.ServerHeader.fromMessageNano(message.header),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.TokenControlMessage.fromMessageNano(message.tokenControlMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationMessage.fromMessageNano(message.invalidationMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatusMessage.fromMessageNano(message.registrationStatusMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationSyncRequestMessage.fromMessageNano(message.registrationSyncRequestMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.ConfigChangeMessage.fromMessageNano(message.configChangeMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.InfoRequestMessage.fromMessageNano(message.infoRequestMessage),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.ErrorMessage.fromMessageNano(message.errorMessage));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerToClientMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerToClientMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ServerToClientMessage();
      msg.header = header.toMessageNano();
      msg.tokenControlMessage = hasTokenControlMessage() ? tokenControlMessage.toMessageNano() : null;
      msg.invalidationMessage = this.invalidationMessage != null ? invalidationMessage.toMessageNano() : null;
      msg.registrationStatusMessage = this.registrationStatusMessage != null ? registrationStatusMessage.toMessageNano() : null;
      msg.registrationSyncRequestMessage = hasRegistrationSyncRequestMessage() ? registrationSyncRequestMessage.toMessageNano() : null;
      msg.configChangeMessage = hasConfigChangeMessage() ? configChangeMessage.toMessageNano() : null;
      msg.infoRequestMessage = this.infoRequestMessage != null ? infoRequestMessage.toMessageNano() : null;
      msg.errorMessage = this.errorMessage != null ? errorMessage.toMessageNano() : null;
      return msg;
    }
  }

  public static final class TokenControlMessage extends ProtoWrapper {
    public static TokenControlMessage create(Bytes newToken) {
      return new TokenControlMessage(newToken);
    }

    public static final TokenControlMessage DEFAULT_INSTANCE = new TokenControlMessage(null);

    private final long __hazzerBits;
    private final Bytes newToken;

    private TokenControlMessage(Bytes newToken) {
      int hazzerBits = 0;
      if (newToken != null) {
        hazzerBits |= 0x1;
        this.newToken = newToken;
      } else {
        this.newToken = Bytes.EMPTY_BYTES;
      }
      this.__hazzerBits = hazzerBits;
    }

    public Bytes getNewToken() { return newToken; }
    public boolean hasNewToken() { return (0x1 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof TokenControlMessage)) { return false; }
      TokenControlMessage other = (TokenControlMessage) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasNewToken() || equals(newToken, other.newToken));
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasNewToken()) {
        result = result * 31 + newToken.hashCode();
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<TokenControlMessage:");
      if (hasNewToken()) {
        builder.append(" new_token=").append(newToken);
      }
      builder.append('>');
    }

    public static TokenControlMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.TokenControlMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static TokenControlMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.TokenControlMessage message) {
      if (message == null) { return null; }
      return new TokenControlMessage(Bytes.fromByteArray(message.newToken));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.TokenControlMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.TokenControlMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.TokenControlMessage();
      msg.newToken = hasNewToken() ? newToken.getByteArray() : null;
      return msg;
    }
  }

  public static final class RegistrationStatus extends ProtoWrapper {
    public static RegistrationStatus create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP registration,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.StatusP status) {
      return new RegistrationStatus(registration, status);
    }

    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP registration;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.StatusP status;

    private RegistrationStatus(com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP registration,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.StatusP status) throws ValidationArgumentException {
      required("registration", registration);
      this.registration = registration;
      required("status", status);
      this.status = status;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP getRegistration() { return registration; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.StatusP getStatus() { return status; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RegistrationStatus)) { return false; }
      RegistrationStatus other = (RegistrationStatus) obj;
      return equals(registration, other.registration)
          && equals(status, other.status);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + registration.hashCode();
      result = result * 31 + status.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RegistrationStatus:");
      builder.append(" registration=").append(registration);
      builder.append(" status=").append(status);
      builder.append('>');
    }

    public static RegistrationStatus parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatus(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RegistrationStatus fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatus message) {
      if (message == null) { return null; }
      return new RegistrationStatus(com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationP.fromMessageNano(message.registration),
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.StatusP.fromMessageNano(message.status));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatus toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatus msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatus();
      msg.registration = registration.toMessageNano();
      msg.status = status.toMessageNano();
      return msg;
    }
  }

  public static final class RegistrationStatusMessage extends ProtoWrapper {
    public static RegistrationStatusMessage create(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatus> registrationStatus) {
      return new RegistrationStatusMessage(registrationStatus);
    }

    private final List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatus> registrationStatus;

    private RegistrationStatusMessage(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatus> registrationStatus) throws ValidationArgumentException {
      this.registrationStatus = required("registration_status", registrationStatus);
    }

    public List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatus> getRegistrationStatus() { return registrationStatus; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RegistrationStatusMessage)) { return false; }
      RegistrationStatusMessage other = (RegistrationStatusMessage) obj;
      return equals(registrationStatus, other.registrationStatus);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + registrationStatus.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RegistrationStatusMessage:");
      builder.append(" registration_status=[").append(registrationStatus).append(']');
      builder.append('>');
    }

    public static RegistrationStatusMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatusMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RegistrationStatusMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatusMessage message) {
      if (message == null) { return null; }
      List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatus> registrationStatus = new ArrayList<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatus>(message.registrationStatus.length);
      for (int i = 0; i < message.registrationStatus.length; i++) {
        registrationStatus.add(com.google.ipc.invalidation.ticl.proto.ClientProtocol.RegistrationStatus.fromMessageNano(message.registrationStatus[i]));
      }
      return new RegistrationStatusMessage(registrationStatus);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatusMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatusMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatusMessage();
      msg.registrationStatus = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationStatus[registrationStatus.size()];
      for (int i = 0; i < msg.registrationStatus.length; i++) {
        msg.registrationStatus[i] = registrationStatus.get(i).toMessageNano();
      }
      return msg;
    }
  }

  public static final class RegistrationSyncRequestMessage extends ProtoWrapper {
    public static RegistrationSyncRequestMessage create() {
      return new RegistrationSyncRequestMessage();
    }

    public static final RegistrationSyncRequestMessage DEFAULT_INSTANCE = new RegistrationSyncRequestMessage();


    private RegistrationSyncRequestMessage() {
    }


    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RegistrationSyncRequestMessage)) { return false; }
      RegistrationSyncRequestMessage other = (RegistrationSyncRequestMessage) obj;
      return true;
    }

    @Override protected int computeHashCode() {
      int result = 1;
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RegistrationSyncRequestMessage:");
      builder.append('>');
    }

    public static RegistrationSyncRequestMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncRequestMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RegistrationSyncRequestMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncRequestMessage message) {
      if (message == null) { return null; }
      return new RegistrationSyncRequestMessage();
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncRequestMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncRequestMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RegistrationSyncRequestMessage();
      return msg;
    }
  }

  public static final class InvalidationMessage extends ProtoWrapper {
    public static InvalidationMessage create(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP> invalidation) {
      return new InvalidationMessage(invalidation);
    }

    private final List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP> invalidation;

    private InvalidationMessage(Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP> invalidation) throws ValidationArgumentException {
      this.invalidation = required("invalidation", invalidation);
    }

    public List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP> getInvalidation() { return invalidation; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof InvalidationMessage)) { return false; }
      InvalidationMessage other = (InvalidationMessage) obj;
      return equals(invalidation, other.invalidation);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + invalidation.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<InvalidationMessage:");
      builder.append(" invalidation=[").append(invalidation).append(']');
      builder.append('>');
    }

    public static InvalidationMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static InvalidationMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationMessage message) {
      if (message == null) { return null; }
      List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP> invalidation = new ArrayList<com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP>(message.invalidation.length);
      for (int i = 0; i < message.invalidation.length; i++) {
        invalidation.add(com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP.fromMessageNano(message.invalidation[i]));
      }
      return new InvalidationMessage(invalidation);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationMessage();
      msg.invalidation = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InvalidationP[invalidation.size()];
      for (int i = 0; i < msg.invalidation.length; i++) {
        msg.invalidation[i] = invalidation.get(i).toMessageNano();
      }
      return msg;
    }
  }

  public static final class InfoRequestMessage extends ProtoWrapper {
    public interface InfoType {
      public static final int GET_PERFORMANCE_COUNTERS = 1;
    }

    public static InfoRequestMessage create(Collection<Integer> infoType) {
      return new InfoRequestMessage(infoType);
    }

    private final List<Integer> infoType;

    private InfoRequestMessage(Collection<Integer> infoType) throws ValidationArgumentException {
      this.infoType = required("info_type", infoType);
    }

    public List<Integer> getInfoType() { return infoType; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof InfoRequestMessage)) { return false; }
      InfoRequestMessage other = (InfoRequestMessage) obj;
      return equals(infoType, other.infoType);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + infoType.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<InfoRequestMessage:");
      builder.append(" info_type=[").append(infoType).append(']');
      builder.append('>');
    }

    public static InfoRequestMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoRequestMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static InfoRequestMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoRequestMessage message) {
      if (message == null) { return null; }
      List<Integer> infoType = new ArrayList<Integer>(message.infoType.length);
      for (int i = 0; i < message.infoType.length; i++) {
        infoType.add(message.infoType[i]);
      }
      return new InfoRequestMessage(infoType);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoRequestMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoRequestMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.InfoRequestMessage();
      msg.infoType = new int[infoType.size()];
      for (int i = 0; i < msg.infoType.length; i++) {
        msg.infoType[i] = infoType.get(i);
      }
      return msg;
    }
  }

  public static final class RateLimitP extends ProtoWrapper {
    public static RateLimitP create(int windowMs,
        int count) {
      return new RateLimitP(windowMs, count);
    }

    private final int windowMs;
    private final int count;

    private RateLimitP(Integer windowMs,
        Integer count) throws ValidationArgumentException {
      required("window_ms", windowMs);
      this.windowMs = windowMs;
      required("count", count);
      this.count = count;
      check(windowMs >= 1000 && windowMs > count, "Invalid window_ms and count");
    }

    public int getWindowMs() { return windowMs; }

    public int getCount() { return count; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RateLimitP)) { return false; }
      RateLimitP other = (RateLimitP) obj;
      return windowMs == other.windowMs
          && count == other.count;
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + hash(windowMs);
      result = result * 31 + hash(count);
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RateLimitP:");
      builder.append(" window_ms=").append(windowMs);
      builder.append(" count=").append(count);
      builder.append('>');
    }

    public static RateLimitP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RateLimitP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RateLimitP fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RateLimitP message) {
      if (message == null) { return null; }
      return new RateLimitP(message.windowMs,
          message.count);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RateLimitP toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RateLimitP msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RateLimitP();
      msg.windowMs = windowMs;
      msg.count = count;
      return msg;
    }
  }

  public static final class ProtocolHandlerConfigP extends ProtoWrapper {
    public static final class Builder {
      public Integer batchingDelayMs;
      public Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RateLimitP> rateLimit;
      public Builder() {
      }

      public ProtocolHandlerConfigP build() {
        return new ProtocolHandlerConfigP(batchingDelayMs, rateLimit);
      }
    }

    public static ProtocolHandlerConfigP create(Integer batchingDelayMs,
        Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RateLimitP> rateLimit) {
      return new ProtocolHandlerConfigP(batchingDelayMs, rateLimit);
    }

    public static final ProtocolHandlerConfigP DEFAULT_INSTANCE = new ProtocolHandlerConfigP(null, null);

    private final long __hazzerBits;
    private final int batchingDelayMs;
    private final List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RateLimitP> rateLimit;

    private ProtocolHandlerConfigP(Integer batchingDelayMs,
        Collection<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RateLimitP> rateLimit) {
      int hazzerBits = 0;
      if (batchingDelayMs != null) {
        hazzerBits |= 0x1;
        this.batchingDelayMs = batchingDelayMs;
      } else {
        this.batchingDelayMs = 500;
      }
      this.rateLimit = optional("rate_limit", rateLimit);
      this.__hazzerBits = hazzerBits;
    }

    public int getBatchingDelayMs() { return batchingDelayMs; }
    public boolean hasBatchingDelayMs() { return (0x1 & __hazzerBits) != 0; }

    public List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RateLimitP> getRateLimit() { return rateLimit; }

    public Builder toBuilder() {
      Builder builder = new Builder();
      if (hasBatchingDelayMs()) {
        builder.batchingDelayMs = batchingDelayMs;
      }
      if (!this.rateLimit.isEmpty()) {
        builder.rateLimit = rateLimit;
      }
      return builder;
    }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ProtocolHandlerConfigP)) { return false; }
      ProtocolHandlerConfigP other = (ProtocolHandlerConfigP) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasBatchingDelayMs() || batchingDelayMs == other.batchingDelayMs)
          && equals(rateLimit, other.rateLimit);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasBatchingDelayMs()) {
        result = result * 31 + hash(batchingDelayMs);
      }
      result = result * 31 + rateLimit.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ProtocolHandlerConfigP:");
      if (hasBatchingDelayMs()) {
        builder.append(" batching_delay_ms=").append(batchingDelayMs);
      }
      builder.append(" rate_limit=[").append(rateLimit).append(']');
      builder.append('>');
    }

    public static ProtocolHandlerConfigP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolHandlerConfigP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ProtocolHandlerConfigP fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolHandlerConfigP message) {
      if (message == null) { return null; }
      List<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RateLimitP> rateLimit = new ArrayList<com.google.ipc.invalidation.ticl.proto.ClientProtocol.RateLimitP>(message.rateLimit.length);
      for (int i = 0; i < message.rateLimit.length; i++) {
        rateLimit.add(com.google.ipc.invalidation.ticl.proto.ClientProtocol.RateLimitP.fromMessageNano(message.rateLimit[i]));
      }
      return new ProtocolHandlerConfigP(message.batchingDelayMs,
          rateLimit);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolHandlerConfigP toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolHandlerConfigP msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ProtocolHandlerConfigP();
      msg.batchingDelayMs = hasBatchingDelayMs() ? batchingDelayMs : null;
      msg.rateLimit = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.RateLimitP[rateLimit.size()];
      for (int i = 0; i < msg.rateLimit.length; i++) {
        msg.rateLimit[i] = rateLimit.get(i).toMessageNano();
      }
      return msg;
    }
  }

  public static final class ClientConfigP extends ProtoWrapper {
    public static final class Builder {
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version;
      public Integer networkTimeoutDelayMs;
      public Integer writeRetryDelayMs;
      public Integer heartbeatIntervalMs;
      public Integer perfCounterDelayMs;
      public Integer maxExponentialBackoffFactor;
      public Integer smearPercent;
      public Boolean isTransient;
      public Integer initialPersistentHeartbeatDelayMs;
      public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolHandlerConfigP protocolHandlerConfig;
      public Boolean channelSupportsOfflineDelivery;
      public Integer offlineHeartbeatThresholdMs;
      public Boolean allowSuppression;
      public Builder(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version,
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolHandlerConfigP protocolHandlerConfig) {
        this.version = version;this.protocolHandlerConfig = protocolHandlerConfig;}

      public ClientConfigP build() {
        return new ClientConfigP(version, networkTimeoutDelayMs, writeRetryDelayMs, heartbeatIntervalMs, perfCounterDelayMs, maxExponentialBackoffFactor, smearPercent, isTransient, initialPersistentHeartbeatDelayMs, protocolHandlerConfig, channelSupportsOfflineDelivery, offlineHeartbeatThresholdMs, allowSuppression);
      }
    }

    public static ClientConfigP create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version,
        Integer networkTimeoutDelayMs,
        Integer writeRetryDelayMs,
        Integer heartbeatIntervalMs,
        Integer perfCounterDelayMs,
        Integer maxExponentialBackoffFactor,
        Integer smearPercent,
        Boolean isTransient,
        Integer initialPersistentHeartbeatDelayMs,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolHandlerConfigP protocolHandlerConfig,
        Boolean channelSupportsOfflineDelivery,
        Integer offlineHeartbeatThresholdMs,
        Boolean allowSuppression) {
      return new ClientConfigP(version, networkTimeoutDelayMs, writeRetryDelayMs, heartbeatIntervalMs, perfCounterDelayMs, maxExponentialBackoffFactor, smearPercent, isTransient, initialPersistentHeartbeatDelayMs, protocolHandlerConfig, channelSupportsOfflineDelivery, offlineHeartbeatThresholdMs, allowSuppression);
    }

    private final long __hazzerBits;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version;
    private final int networkTimeoutDelayMs;
    private final int writeRetryDelayMs;
    private final int heartbeatIntervalMs;
    private final int perfCounterDelayMs;
    private final int maxExponentialBackoffFactor;
    private final int smearPercent;
    private final boolean isTransient;
    private final int initialPersistentHeartbeatDelayMs;
    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolHandlerConfigP protocolHandlerConfig;
    private final boolean channelSupportsOfflineDelivery;
    private final int offlineHeartbeatThresholdMs;
    private final boolean allowSuppression;

    private ClientConfigP(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version version,
        Integer networkTimeoutDelayMs,
        Integer writeRetryDelayMs,
        Integer heartbeatIntervalMs,
        Integer perfCounterDelayMs,
        Integer maxExponentialBackoffFactor,
        Integer smearPercent,
        Boolean isTransient,
        Integer initialPersistentHeartbeatDelayMs,
        com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolHandlerConfigP protocolHandlerConfig,
        Boolean channelSupportsOfflineDelivery,
        Integer offlineHeartbeatThresholdMs,
        Boolean allowSuppression) throws ValidationArgumentException {
      int hazzerBits = 0;
      required("version", version);
      this.version = version;
      if (networkTimeoutDelayMs != null) {
        hazzerBits |= 0x1;
        this.networkTimeoutDelayMs = networkTimeoutDelayMs;
      } else {
        this.networkTimeoutDelayMs = 60000;
      }
      if (writeRetryDelayMs != null) {
        hazzerBits |= 0x2;
        this.writeRetryDelayMs = writeRetryDelayMs;
      } else {
        this.writeRetryDelayMs = 10000;
      }
      if (heartbeatIntervalMs != null) {
        hazzerBits |= 0x4;
        this.heartbeatIntervalMs = heartbeatIntervalMs;
      } else {
        this.heartbeatIntervalMs = 1200000;
      }
      if (perfCounterDelayMs != null) {
        hazzerBits |= 0x8;
        this.perfCounterDelayMs = perfCounterDelayMs;
      } else {
        this.perfCounterDelayMs = 21600000;
      }
      if (maxExponentialBackoffFactor != null) {
        hazzerBits |= 0x10;
        this.maxExponentialBackoffFactor = maxExponentialBackoffFactor;
      } else {
        this.maxExponentialBackoffFactor = 500;
      }
      if (smearPercent != null) {
        hazzerBits |= 0x20;
        this.smearPercent = smearPercent;
      } else {
        this.smearPercent = 20;
      }
      if (isTransient != null) {
        hazzerBits |= 0x40;
        this.isTransient = isTransient;
      } else {
        this.isTransient = false;
      }
      if (initialPersistentHeartbeatDelayMs != null) {
        hazzerBits |= 0x80;
        this.initialPersistentHeartbeatDelayMs = initialPersistentHeartbeatDelayMs;
      } else {
        this.initialPersistentHeartbeatDelayMs = 2000;
      }
      required("protocol_handler_config", protocolHandlerConfig);
      this.protocolHandlerConfig = protocolHandlerConfig;
      if (channelSupportsOfflineDelivery != null) {
        hazzerBits |= 0x100;
        this.channelSupportsOfflineDelivery = channelSupportsOfflineDelivery;
      } else {
        this.channelSupportsOfflineDelivery = false;
      }
      if (offlineHeartbeatThresholdMs != null) {
        hazzerBits |= 0x200;
        this.offlineHeartbeatThresholdMs = offlineHeartbeatThresholdMs;
      } else {
        this.offlineHeartbeatThresholdMs = 60000;
      }
      if (allowSuppression != null) {
        hazzerBits |= 0x400;
        this.allowSuppression = allowSuppression;
      } else {
        this.allowSuppression = true;
      }
      this.__hazzerBits = hazzerBits;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version getVersion() { return version; }

    public int getNetworkTimeoutDelayMs() { return networkTimeoutDelayMs; }
    public boolean hasNetworkTimeoutDelayMs() { return (0x1 & __hazzerBits) != 0; }

    public int getWriteRetryDelayMs() { return writeRetryDelayMs; }
    public boolean hasWriteRetryDelayMs() { return (0x2 & __hazzerBits) != 0; }

    public int getHeartbeatIntervalMs() { return heartbeatIntervalMs; }
    public boolean hasHeartbeatIntervalMs() { return (0x4 & __hazzerBits) != 0; }

    public int getPerfCounterDelayMs() { return perfCounterDelayMs; }
    public boolean hasPerfCounterDelayMs() { return (0x8 & __hazzerBits) != 0; }

    public int getMaxExponentialBackoffFactor() { return maxExponentialBackoffFactor; }
    public boolean hasMaxExponentialBackoffFactor() { return (0x10 & __hazzerBits) != 0; }

    public int getSmearPercent() { return smearPercent; }
    public boolean hasSmearPercent() { return (0x20 & __hazzerBits) != 0; }

    public boolean getIsTransient() { return isTransient; }
    public boolean hasIsTransient() { return (0x40 & __hazzerBits) != 0; }

    public int getInitialPersistentHeartbeatDelayMs() { return initialPersistentHeartbeatDelayMs; }
    public boolean hasInitialPersistentHeartbeatDelayMs() { return (0x80 & __hazzerBits) != 0; }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolHandlerConfigP getProtocolHandlerConfig() { return protocolHandlerConfig; }

    public boolean getChannelSupportsOfflineDelivery() { return channelSupportsOfflineDelivery; }
    public boolean hasChannelSupportsOfflineDelivery() { return (0x100 & __hazzerBits) != 0; }

    public int getOfflineHeartbeatThresholdMs() { return offlineHeartbeatThresholdMs; }
    public boolean hasOfflineHeartbeatThresholdMs() { return (0x200 & __hazzerBits) != 0; }

    public boolean getAllowSuppression() { return allowSuppression; }
    public boolean hasAllowSuppression() { return (0x400 & __hazzerBits) != 0; }

    public Builder toBuilder() {
      Builder builder = new Builder(version, protocolHandlerConfig);
      if (hasNetworkTimeoutDelayMs()) {
        builder.networkTimeoutDelayMs = networkTimeoutDelayMs;
      }
      if (hasWriteRetryDelayMs()) {
        builder.writeRetryDelayMs = writeRetryDelayMs;
      }
      if (hasHeartbeatIntervalMs()) {
        builder.heartbeatIntervalMs = heartbeatIntervalMs;
      }
      if (hasPerfCounterDelayMs()) {
        builder.perfCounterDelayMs = perfCounterDelayMs;
      }
      if (hasMaxExponentialBackoffFactor()) {
        builder.maxExponentialBackoffFactor = maxExponentialBackoffFactor;
      }
      if (hasSmearPercent()) {
        builder.smearPercent = smearPercent;
      }
      if (hasIsTransient()) {
        builder.isTransient = isTransient;
      }
      if (hasInitialPersistentHeartbeatDelayMs()) {
        builder.initialPersistentHeartbeatDelayMs = initialPersistentHeartbeatDelayMs;
      }
      if (hasChannelSupportsOfflineDelivery()) {
        builder.channelSupportsOfflineDelivery = channelSupportsOfflineDelivery;
      }
      if (hasOfflineHeartbeatThresholdMs()) {
        builder.offlineHeartbeatThresholdMs = offlineHeartbeatThresholdMs;
      }
      if (hasAllowSuppression()) {
        builder.allowSuppression = allowSuppression;
      }
      return builder;
    }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ClientConfigP)) { return false; }
      ClientConfigP other = (ClientConfigP) obj;
      return __hazzerBits == other.__hazzerBits
          && equals(version, other.version)
          && (!hasNetworkTimeoutDelayMs() || networkTimeoutDelayMs == other.networkTimeoutDelayMs)
          && (!hasWriteRetryDelayMs() || writeRetryDelayMs == other.writeRetryDelayMs)
          && (!hasHeartbeatIntervalMs() || heartbeatIntervalMs == other.heartbeatIntervalMs)
          && (!hasPerfCounterDelayMs() || perfCounterDelayMs == other.perfCounterDelayMs)
          && (!hasMaxExponentialBackoffFactor() || maxExponentialBackoffFactor == other.maxExponentialBackoffFactor)
          && (!hasSmearPercent() || smearPercent == other.smearPercent)
          && (!hasIsTransient() || isTransient == other.isTransient)
          && (!hasInitialPersistentHeartbeatDelayMs() || initialPersistentHeartbeatDelayMs == other.initialPersistentHeartbeatDelayMs)
          && equals(protocolHandlerConfig, other.protocolHandlerConfig)
          && (!hasChannelSupportsOfflineDelivery() || channelSupportsOfflineDelivery == other.channelSupportsOfflineDelivery)
          && (!hasOfflineHeartbeatThresholdMs() || offlineHeartbeatThresholdMs == other.offlineHeartbeatThresholdMs)
          && (!hasAllowSuppression() || allowSuppression == other.allowSuppression);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      result = result * 31 + version.hashCode();
      if (hasNetworkTimeoutDelayMs()) {
        result = result * 31 + hash(networkTimeoutDelayMs);
      }
      if (hasWriteRetryDelayMs()) {
        result = result * 31 + hash(writeRetryDelayMs);
      }
      if (hasHeartbeatIntervalMs()) {
        result = result * 31 + hash(heartbeatIntervalMs);
      }
      if (hasPerfCounterDelayMs()) {
        result = result * 31 + hash(perfCounterDelayMs);
      }
      if (hasMaxExponentialBackoffFactor()) {
        result = result * 31 + hash(maxExponentialBackoffFactor);
      }
      if (hasSmearPercent()) {
        result = result * 31 + hash(smearPercent);
      }
      if (hasIsTransient()) {
        result = result * 31 + hash(isTransient);
      }
      if (hasInitialPersistentHeartbeatDelayMs()) {
        result = result * 31 + hash(initialPersistentHeartbeatDelayMs);
      }
      result = result * 31 + protocolHandlerConfig.hashCode();
      if (hasChannelSupportsOfflineDelivery()) {
        result = result * 31 + hash(channelSupportsOfflineDelivery);
      }
      if (hasOfflineHeartbeatThresholdMs()) {
        result = result * 31 + hash(offlineHeartbeatThresholdMs);
      }
      if (hasAllowSuppression()) {
        result = result * 31 + hash(allowSuppression);
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ClientConfigP:");
      builder.append(" version=").append(version);
      if (hasNetworkTimeoutDelayMs()) {
        builder.append(" network_timeout_delay_ms=").append(networkTimeoutDelayMs);
      }
      if (hasWriteRetryDelayMs()) {
        builder.append(" write_retry_delay_ms=").append(writeRetryDelayMs);
      }
      if (hasHeartbeatIntervalMs()) {
        builder.append(" heartbeat_interval_ms=").append(heartbeatIntervalMs);
      }
      if (hasPerfCounterDelayMs()) {
        builder.append(" perf_counter_delay_ms=").append(perfCounterDelayMs);
      }
      if (hasMaxExponentialBackoffFactor()) {
        builder.append(" max_exponential_backoff_factor=").append(maxExponentialBackoffFactor);
      }
      if (hasSmearPercent()) {
        builder.append(" smear_percent=").append(smearPercent);
      }
      if (hasIsTransient()) {
        builder.append(" is_transient=").append(isTransient);
      }
      if (hasInitialPersistentHeartbeatDelayMs()) {
        builder.append(" initial_persistent_heartbeat_delay_ms=").append(initialPersistentHeartbeatDelayMs);
      }
      builder.append(" protocol_handler_config=").append(protocolHandlerConfig);
      if (hasChannelSupportsOfflineDelivery()) {
        builder.append(" channel_supports_offline_delivery=").append(channelSupportsOfflineDelivery);
      }
      if (hasOfflineHeartbeatThresholdMs()) {
        builder.append(" offline_heartbeat_threshold_ms=").append(offlineHeartbeatThresholdMs);
      }
      if (hasAllowSuppression()) {
        builder.append(" allow_suppression=").append(allowSuppression);
      }
      builder.append('>');
    }

    public static ClientConfigP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientConfigP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ClientConfigP fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientConfigP message) {
      if (message == null) { return null; }
      return new ClientConfigP(com.google.ipc.invalidation.ticl.proto.ClientProtocol.Version.fromMessageNano(message.version),
          message.networkTimeoutDelayMs,
          message.writeRetryDelayMs,
          message.heartbeatIntervalMs,
          message.perfCounterDelayMs,
          message.maxExponentialBackoffFactor,
          message.smearPercent,
          message.isTransient,
          message.initialPersistentHeartbeatDelayMs,
          com.google.ipc.invalidation.ticl.proto.ClientProtocol.ProtocolHandlerConfigP.fromMessageNano(message.protocolHandlerConfig),
          message.channelSupportsOfflineDelivery,
          message.offlineHeartbeatThresholdMs,
          message.allowSuppression);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientConfigP toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientConfigP msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ClientConfigP();
      msg.version = version.toMessageNano();
      msg.networkTimeoutDelayMs = hasNetworkTimeoutDelayMs() ? networkTimeoutDelayMs : null;
      msg.writeRetryDelayMs = hasWriteRetryDelayMs() ? writeRetryDelayMs : null;
      msg.heartbeatIntervalMs = hasHeartbeatIntervalMs() ? heartbeatIntervalMs : null;
      msg.perfCounterDelayMs = hasPerfCounterDelayMs() ? perfCounterDelayMs : null;
      msg.maxExponentialBackoffFactor = hasMaxExponentialBackoffFactor() ? maxExponentialBackoffFactor : null;
      msg.smearPercent = hasSmearPercent() ? smearPercent : null;
      msg.isTransient = hasIsTransient() ? isTransient : null;
      msg.initialPersistentHeartbeatDelayMs = hasInitialPersistentHeartbeatDelayMs() ? initialPersistentHeartbeatDelayMs : null;
      msg.protocolHandlerConfig = protocolHandlerConfig.toMessageNano();
      msg.channelSupportsOfflineDelivery = hasChannelSupportsOfflineDelivery() ? channelSupportsOfflineDelivery : null;
      msg.offlineHeartbeatThresholdMs = hasOfflineHeartbeatThresholdMs() ? offlineHeartbeatThresholdMs : null;
      msg.allowSuppression = hasAllowSuppression() ? allowSuppression : null;
      return msg;
    }
  }

  public static final class ConfigChangeMessage extends ProtoWrapper {
    public static ConfigChangeMessage create(Long nextMessageDelayMs) {
      return new ConfigChangeMessage(nextMessageDelayMs);
    }

    public static final ConfigChangeMessage DEFAULT_INSTANCE = new ConfigChangeMessage(null);

    private final long __hazzerBits;
    private final long nextMessageDelayMs;

    private ConfigChangeMessage(Long nextMessageDelayMs) throws ValidationArgumentException {
      int hazzerBits = 0;
      if (nextMessageDelayMs != null) {
        hazzerBits |= 0x1;
        positive("next_message_delay_ms", nextMessageDelayMs);
        this.nextMessageDelayMs = nextMessageDelayMs;
      } else {
        this.nextMessageDelayMs = 0;
      }
      this.__hazzerBits = hazzerBits;
    }

    public long getNextMessageDelayMs() { return nextMessageDelayMs; }
    public boolean hasNextMessageDelayMs() { return (0x1 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ConfigChangeMessage)) { return false; }
      ConfigChangeMessage other = (ConfigChangeMessage) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasNextMessageDelayMs() || nextMessageDelayMs == other.nextMessageDelayMs);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasNextMessageDelayMs()) {
        result = result * 31 + hash(nextMessageDelayMs);
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ConfigChangeMessage:");
      if (hasNextMessageDelayMs()) {
        builder.append(" next_message_delay_ms=").append(nextMessageDelayMs);
      }
      builder.append('>');
    }

    public static ConfigChangeMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ConfigChangeMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ConfigChangeMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ConfigChangeMessage message) {
      if (message == null) { return null; }
      return new ConfigChangeMessage(message.nextMessageDelayMs);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ConfigChangeMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ConfigChangeMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ConfigChangeMessage();
      msg.nextMessageDelayMs = hasNextMessageDelayMs() ? nextMessageDelayMs : null;
      return msg;
    }
  }

  public static final class ErrorMessage extends ProtoWrapper {
    public interface Code {
      public static final int AUTH_FAILURE = 1;
      public static final int UNKNOWN_FAILURE = 10000;
    }

    public static ErrorMessage create(int code,
        String description) {
      return new ErrorMessage(code, description);
    }

    private final int code;
    private final String description;

    private ErrorMessage(Integer code,
        String description) throws ValidationArgumentException {
      required("code", code);
      this.code = code;
      required("description", description);
      this.description = description;
    }

    public int getCode() { return code; }

    public String getDescription() { return description; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ErrorMessage)) { return false; }
      ErrorMessage other = (ErrorMessage) obj;
      return code == other.code
          && equals(description, other.description);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      result = result * 31 + hash(code);
      result = result * 31 + description.hashCode();
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ErrorMessage:");
      builder.append(" code=").append(code);
      builder.append(" description=").append(description);
      builder.append('>');
    }

    public static ErrorMessage parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ErrorMessage(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ErrorMessage fromMessageNano(com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ErrorMessage message) {
      if (message == null) { return null; }
      return new ErrorMessage(message.code,
          message.description);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ErrorMessage toMessageNano() {
      com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ErrorMessage msg = new com.google.protos.ipc.invalidation.nano.NanoClientProtocol.ErrorMessage();
      msg.code = code;
      msg.description = description;
      return msg;
    }
  }
}
